From 805b026f92df47453347f622c7ac6866193fe8c7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 4 Nov 2014 19:40:06 -0800 Subject: [PATCH] Build lib tests and libraries in parallel When building unit tests for a library, we don't need the library itself to be built beforehand, so the two can be built in parallel. If the crate takes awhile to compile, this shows some excellent wall-time speedups. --- src/cargo/ops/cargo_rustc/job_queue.rs | 21 +++++++++++++-------- src/cargo/ops/cargo_rustc/mod.rs | 13 ++++++++----- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/job_queue.rs b/src/cargo/ops/cargo_rustc/job_queue.rs index 86d8b9982..554b3ca2f 100644 --- a/src/cargo/ops/cargo_rustc/job_queue.rs +++ b/src/cargo/ops/cargo_rustc/job_queue.rs @@ -53,7 +53,8 @@ pub enum TargetStage { StageRunCustomBuild, StageLibraries, StageBinaries, - StageTests, + StageLibraryTests, + StageBinaryTests, } type Message = (PackageId, TargetStage, Freshness, CargoResult<()>); @@ -284,13 +285,17 @@ impl<'a> Dependency<(&'a Resolve, &'a PackageSet)> // do not depend on dev-dependencies. StageBinaries => vec![(id, StageLibraries)], - // Tests depend on all non-transitive dependencies - // (dev-dependencies) in addition to the library stage for this - // package. - StageTests => { - let mut base = vec![(id, StageLibraries)]; - base.extend(deps.filter(|&(_, dep)| !dep.is_transitive()) - .map(|(id, _)| (id, StageLibraries))); + // Tests depend on all dependencies (including dev-dependencies) in + // addition to the library stage for this package. Note, however, + // that library tests only need to depend the custom build command + // being run, not the libraries themselves. + StageBinaryTests | StageLibraryTests => { + let mut base = if stage == StageBinaryTests { + vec![(id, StageLibraries)] + } else { + vec![(id, StageRunCustomBuild)] + }; + base.extend(deps.map(|(id, _)| (id, StageLibraries))); base } } diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 647fb0e6f..9b2c3bf78 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -166,7 +166,8 @@ fn compile<'a, 'b>(targets: &[&'a Target], pkg: &'a Package, // // Each target has its own concept of freshness to ensure incremental // rebuilds on the *target* granularity, not the *package* granularity. - let (mut libs, mut bins, mut tests) = (Vec::new(), Vec::new(), Vec::new()); + let (mut libs, mut bins, mut lib_tests, mut bin_tests) = + (Vec::new(), Vec::new(), Vec::new(), Vec::new()); let (mut build_custom, mut run_custom) = (Vec::new(), Vec::new()); for &target in targets.iter() { if target.get_profile().is_custom_build() { @@ -193,9 +194,10 @@ fn compile<'a, 'b>(targets: &[&'a Target], pkg: &'a Package, target.get_profile().is_test(), target.get_profile().is_custom_build()) { (_, _, true) => &mut build_custom, - (_, true, _) => &mut tests, - (true, _, _) => &mut libs, - (false, false, _) if target.get_profile().get_env() == "test" => &mut tests, + (true, true, _) => &mut lib_tests, + (false, true, _) => &mut bin_tests, + (true, false, _) => &mut libs, + (false, false, _) if target.get_profile().get_env() == "test" => &mut bin_tests, (false, false, _) => &mut bins, }; for (work, kind) in work.into_iter() { @@ -244,7 +246,8 @@ fn compile<'a, 'b>(targets: &[&'a Target], pkg: &'a Package, jobs.enqueue(pkg, jq::StageLibraries, libs); jobs.enqueue(pkg, jq::StageBinaries, bins); - jobs.enqueue(pkg, jq::StageTests, tests); + jobs.enqueue(pkg, jq::StageBinaryTests, bin_tests); + jobs.enqueue(pkg, jq::StageLibraryTests, lib_tests); Ok(()) } -- 2.30.2